using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using CoachingOrganizer.Logic.Models.Tools.MoodLevel;
using CoachingOrganizer.Android.Helpers;
using Android.Graphics;
using CoachingOrganizer.Android.Adapters.Tools.MoodLevel;

namespace CoachingOrganizer.Android.Activities.Tools.MoodLevel
{
    [Activity(Label = "@string/ApplicationName")]
    public class MoodDetailsActivity : Activity
    {
        private MoodLevelModel _model;
        private Bitmap _lastChartBitmap;
        private bool _valuesChanged;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            _model = UIHelper.GetActivityModel<MoodLevelModel>(this, bundle);
            SetContentView(Resource.Layout.MoodLevelDetailsLayout);
            InitLayout();
            Init();
            HookModel();
        }

        protected override void OnResume()
        {
            base.OnResume();
            //HookModel();
        }

        protected override void OnPause()
        {
            base.OnPause();
            //UnhookModel();
        }

        private void InitLayout()
        {
            TabHost tabHost = FindViewById<TabHost>(Resource.Id.moodTabHost);
            tabHost.Setup();
            TabHost.TabSpec spec = tabHost.NewTabSpec("tab1");
            spec.SetContent(Resource.Id.moodInputLinearLayout);
            spec.SetIndicator(Resources.GetString(Resource.String.MoodInputTabTitle));
            tabHost.AddTab(spec);
            spec = tabHost.NewTabSpec("tab2");
            spec.SetContent(Resource.Id.moodChartLinearLayout);
            spec.SetIndicator(Resources.GetString(Resource.String.MoodChartTabTitle));
            tabHost.AddTab(spec);
        }

        private async void Init()
        {
            using (System.Threading.CancellationTokenSource cancellation = new System.Threading.CancellationTokenSource())
                await _model.LoadMoodValuesAsync(cancellation.Token);
        }

        private void HookModel()
        {
            _model.ValuesCollectionChanged += Model_ValuesCollectionChanged;
            _model.SelectedDayChanged += Model_SelectedDayChanged;
            Spinner moodDaysSpinner = FindViewById<Spinner>(Resource.Id.moodDaysSpinner);
            moodDaysSpinner.Adapter = new MoodDaysAdapter(this, _model);
            moodDaysSpinner.ItemSelected += (sender, e) =>
                _model.SelectedDay = _model.Days.ElementAtOrDefault(moodDaysSpinner.SelectedItemPosition);
        }

        private void HookDayCacheModel(Activity activity, MoodDayCacheModel moodDayCacheModel)
        {
            Button saveMoodDetailsChartButton = activity.FindViewById<Button>(Resource.Id.saveMoodDetailsChartButton);
            saveMoodDetailsChartButton.Click += (sender, e) => moodDayCacheModel.Save();           
            ListView moodValuesListView = activity.FindViewById<ListView>(Resource.Id.moodValuesListView);
            if (moodValuesListView.Adapter != null)
                moodValuesListView.Adapter.Dispose();
            moodValuesListView.Adapter = new MoodValuesAdapter(activity, moodDayCacheModel);
            ImageView moodChartImageView = activity.FindViewById<ImageView>(Resource.Id.moodChartImageView);
            LinearLayout moodChartLinearLayout = activity.FindViewById<LinearLayout>(Resource.Id.moodChartLinearLayout);
            //moodChartLinearLayout. += (sender, e) => DrawMoodChart(moodChartImageView, _model.EnumerateDayValues(moodDayCacheModel.Date.Date).ToArray(), moodChartLinearLayout.Width, moodChartLinearLayout.Height);
            TabHost tabHost = FindViewById<TabHost>(Resource.Id.moodTabHost);
            LinearLayout moodLevelTabsLinearLayout = FindViewById<LinearLayout>(Resource.Id.moodLevelTabsLinearLayout);
            tabHost.TabChanged += (sender, e) =>
            {
                if (_valuesChanged && tabHost.CurrentTab == 1 && _model.SelectedDay != null)
                {
                    DrawMoodChart(moodChartImageView, _model.EnumerateDayValues(moodDayCacheModel.Date.Date).ToArray(), moodLevelTabsLinearLayout.Width, moodLevelTabsLinearLayout.Height);
                    _valuesChanged = false;
                }
            };
            if (_model.SelectedDay != null)
                DrawMoodChart(moodChartImageView, _model.EnumerateDayValues(moodDayCacheModel.Date.Date).ToArray(), moodLevelTabsLinearLayout.Width, moodLevelTabsLinearLayout.Height);
        }

        private void DrawMoodChart(ImageView moodChartImageView, MoodValueModel[] moodValues, int width, int height)
        {
            if (_lastChartBitmap != null)
            {
                _lastChartBitmap.Dispose();
                _lastChartBitmap = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            if (width == 0 || height == 0)
                return;
            Bitmap chartBitmap = _lastChartBitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
            Canvas drawingContext = new Canvas(chartBitmap);
            drawingContext.DrawRect(0f, 0f, width, height, new Paint { Color = Color.White });
            drawingContext.DrawRect(2f, 2f, width - 2f, height - 2f, new Paint { Color = Color.Black });
            float horizontalOffset = (float)drawingContext.Width / (float)moodValues.Length;
            float verticalScale = (float)drawingContext.Height / 10f;
            float verticalBaseOffset = (float)drawingContext.Height / 2f;
            Paint pen = new Paint()
            {
                Color = Color.Red
            };
            int i = 0;
            for (float x = 0f; x < drawingContext.Width && i < moodValues.Length - 1; x += horizontalOffset, i++)
                drawingContext.DrawLine(x, verticalBaseOffset - (float)moodValues[i].Value * verticalScale, x + horizontalOffset, verticalBaseOffset - (float)moodValues[i + 1].Value * verticalScale, pen);
            moodChartImageView.SetImageBitmap(chartBitmap);
        }


        private void UnhookModel()
        {
            throw new NotImplementedException();
        }

        private void Model_ValuesCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            _valuesChanged = true;
        }

        private void Model_SelectedDayChanged(object sender, EventArgs e)
        {
            HookDayCacheModel(this, _model.SelectedDay);
        }
    }
}